<?php
/**
 * Created by PhpStorm.
 * User: quyang
 * Date: 2017/2/21
 * Time: 16:29
 */
namespace Home\Server;
use Think\Server;
class SmsLogServer {

    protected $current_table;  //當月表

    protected $Last_Month_Table;

    public function __construct()
    {

        $this->current_table = 'tp_sms_log_' . date('Ym');

        $this->Last_Month_Table = 'tp_sms_log_' . date( 'Ym',strtotime('-1 month') );

        $this->now_Time = time();

        $this->queryCurrentTable();

    }

    /**
     * @Desc  : 短信回调查询是否存在
     * @Author：quyang
     * @Param ：
     * @Time  ：2017/3/1 13:38
     * @Update：2017/3/1
     **/
    public function queryMsgId( $msgId )
    {

        $where = "`f_massage_id`='{$msgId}'";

        return $this->getConditionTable_Result(
            date( 'Y-m-01' , strtotime(  '-1 month' ) ),
            date( 'Y-m-d' ),
            'f_parcel_id,f_massage_id,f_send_sms_type,f_type',
            $where
        )->find();

    }

    /**
     * @Desc  : 根据短信id修改发送状态
     * @Author：quyang
     * @Param ：
     * @Time  ：2017/3/1 14:04
     * @Update：2017/3/1
     **/
    public function updateSuccessStatus( $msgId , $Array , $tableName = null )
    {

        $where['f_massage_id'] = $msgId;

        if ( !empty( $tableName ) ){
            return ( new \Think\Model( $tableName ) )->where( $where )->save( $Array );
        }

        $table1 = ( new \Think\Model( $this->current_table ) )->where( $where )->save( $Array );

        $table2 = ( new \Think\Model( $this->Last_Month_Table ) )->where( $where )->save( $Array );

        return $table1 || $table2 ? TRUE : FALSE;

    }

    /**
     * @Desc  : 统计12小时发送短信次数，超过三次不允许发送
     * @Author：quyang
     * @Param ：
     * @Time  ：2017/2/28 17:42
     * @Update：2017/2/28
     **/
    public function countSmsLog( $parcelId )
    {

        $where = '`f_parcel_id`='.$parcelId.'';

        return $this->getConditionTable_Result(
            date( 'Y-m-d' ),
            date( 'Y-m-d' ),
            'f_parcel_id',
            $where
            )->count('f_parcel_id');

    }

    /**
     * @Desc  : 发送短信写入log
     * @Author：quyang
     * @Param ：$data 包裹数据  $msgId  短信id  $notice 发送状态  $content  短信内容  $num  扣费条数  $sendtype  发送类型
     * @Time  ：2017/3/1 16:54
     * @Update：2017/3/1
     **/
    public function addLog( $data , $msgId , $notice , $content , $num , $sendtype , $type )
    {

        $where = array(
            'f_parcel_id'       =>$data['packageCode'],
            'f_massage_id'      =>$msgId,
            'f_send_time'       =>date('YmdHis'),
            'f_send_time_stamp' =>time(),
            'f_type'            =>empty( $type ) ? 'DX' : $type,
            'f_mail_no'         =>$data['mailNo'],
            'f_recipient_mobile'=>$data['mobile'],
            'f_sms_content'     =>$content,
            'f_send_notice'     =>$notice,    //短信发送状态
            'f_station_id'      =>$data['stationId'],
            'f_reduce_num'      =>$num,    //短信扣费条数
            'f_send_sms_type'   =>$sendtype    //短信发送类型
        );

        $this->addParcelLog( $where );

    }

    /**
     * @desc  : 添加队列数据批量
     * @author：quyang
     * @param ：$Array:添加數據
     * @time  ：2017/2/28 14:52
     * @update：2017/2/28
     **/
    public function addParcelLog( $Array )
    {

        //驗證當月表是否存在
//        if ( !$this->queryCurrentTable() ){
//            $this->insertTable();
//        }

        return ( new \Think\Model( $this->current_table ) )->add( $Array );

    }

    /**
     * @desc  : 查詢當月表是否存在
     * @author：quyang
     * @param ：
     * @time  ：2017/2/21 17:30
     * @update：2017/2/21
     **/
    public function queryCurrentTable(  )
    {

        $table = ( new \Think\Model() )->query( "SHOW TABLES LIKE '{$this->current_table}'" ) ;

        //表不存在則創建
        if ( !$table ){

            $this->insertTable();

        }

        return true;

    }

    /**
     * Function getConditionTable_Result
     * @param $startDate
     * @param $endDate
     * @param $fields
     * @param $where
     * @return \Think\Model
     *
     * Author: 黄盖
     * Date: 2017-2-7 16:43
     * Info: 获取查询连表数据
     */
    public function getConditionTable_Result( $startDate, $endDate, $fields,  $where )
    {
        $tableName_Array = $NO_ExistsDate = Array();

        //查询哪些表
        if( ! empty( $startDate ) && ! empty( $endDate ) )
        {
            //2017-01-30   2017-03-01
            $startDateInfo = explode('-', $startDate);
            $endDateInfo   = explode('-', $endDate);

            //获取区间日期有哪些年月
            $MonthData = $this ->getYearMonth( $startDateInfo[0], $startDateInfo[1], $endDateInfo[0], $endDateInfo[1] );

            //获取存在哪些表
            $TableExists = ( new \Think\Model() ) ->query( "SHOW TABLES LIKE 'tp_sms_log_%';" );
            $ExistsName = Array();

            //提取分表名
            foreach( $TableExists as $TKey => $TVal )
            {
                sort($TVal);
                $ExistsName[] = $TVal[0];
            }

            foreach( $MonthData as $MKey => $MVal )
            {
                if( in_array( 'tp_sms_log_' . $MVal, $ExistsName ) )
                {
                    $tableName_Array[] = 'tp_sms_log_' . $MVal;
                }
                else
                {
                    $NO_ExistsDate[] = $MVal;
                }
            }
        }
        //默认两个月
        else
        {
            $tableName_Array[] = $this ->current_table;
            $tableName_Array[] = $this ->Last_Month_Table;
        }

        $UNION_Tables = '(';

        //交联主表
        if( ! empty( $NO_ExistsDate ) )
        {
            $UNION_Tables .= "
                            (
                                SELECT 
                                    {$fields}, 'tp_sms_log' AS `table_name`
                                FROM
                                    `tp_sms_log`
                                WHERE
                                    {$where} AND `f_send_time_stamp` BETWEEN '". strtotime( $startDate . ' 00:00:00' ) ."' AND '". ( count( $tableName_Array ) > 0 ? strtotime('+1 month', strtotime( substr( $NO_ExistsDate[count( $NO_ExistsDate ) - 1], 0, 4 ) . '-' . substr( $NO_ExistsDate[count( $NO_ExistsDate ) - 1], 4, 2 ) . '-01 00:00:00' )) : strtotime( $endDate . ' 23:59:59' ) ) ."'
                            )
                        ";

            $UNION_Tables .= 'UNION';
        }

        //交联分表
        foreach( $tableName_Array as $TKey => $TVal )
        {
            $TimeWhere = '';

            //查询结束时间节点
            if( count( $tableName_Array ) - 1 == $TKey )
            {
                $TimeWhere .= ' AND `f_send_time_stamp` <= ' . strtotime( $endDate . ' 23:59:59' );
            }

            //查询开始时间节点
            if( empty( $NO_ExistsDate ) && $TKey == 0 )
            {
                $TimeWhere .= ' AND `f_send_time_stamp` >= ' . strtotime( $startDate . ' 00:00:00' );
            }


            $UNION_Tables .= "
                            (
                                SELECT 
                                    {$fields}, '{$TVal}' AS `table_name`
                                FROM
                                    `{$TVal}`
                                WHERE
                                    {$where} {$TimeWhere}
                            )
                        ";

            $UNION_Tables .= 'UNION';
        }

        $UNION_Tables = substr( $UNION_Tables, 0, -5 );

        $UNION_Tables .= ') AS `temp_sms_log`';

        //返回连表资源
        return ( new \Think\Model() )
            ->field('*')
            ->table( $UNION_Tables );
    }

    /**
     * Function getYearMonth
     * @param $startYear
     * @param $startMonth
     * @param $endYear
     * @param $endMonth
     * @return array
     *
     * Author: 黄盖
     * Date: 2017-2-7 16:43
     * Info: 根据日期区间, 获取中间的年月
     */
    public function getYearMonth( $startYear, $startMonth, $endYear, $endMonth )
    {
        $MonthData = Array();
        $startMonth = intval( $startMonth );
        $endMonth = intval( $endMonth );

        for( $i = 0; $i <= $endYear - $startYear; $i++ )
        {
            $Now_Year = $startYear + $i;

            if( $Now_Year == $startYear && $Now_Year == $endYear )
            {
                for( $s = $startMonth; $s <= $endMonth; $s ++ )
                {
                    $MonthData[] = $Now_Year . ( $s < 10 ? '0' . $s : $s );
                }
            }
            else if( $Now_Year == $startYear )
            {
                for( $s = $startMonth; $s <= 12; $s ++ )
                {
                    $MonthData[] = $Now_Year . ( $s < 10 ? '0' . $s : $s );
                }
            }
            else if( $Now_Year == $endYear )
            {
                for( $s = 1; $s <= $endMonth; $s ++ )
                {
                    $MonthData[] = $Now_Year . ( $s < 10 ? '0' . $s : $s );
                }
            }
            else
            {
                for( $s = 1; $s <= 12; $s ++ )
                {
                    $MonthData[] = $Now_Year . ( $s < 10 ? '0' . $s : $s );
                }
            }

        }

        sort( $MonthData );

        return $MonthData;
    }

    /**
     * @desc  : 自動創建當月表
     * @author：quyang
     * @param ：
     * @time  ：2017/2/21 17:41
     * @update：2017/2/21
     **/
    public function insertTable()
    {

        ( new \Think\Model() )->execute("
                CREATE TABLE `{$this->current_table}` (
                `f_parcel_id` int(10) NOT NULL COMMENT '站点id',
                `f_massage_id` varchar(50) NOT NULL DEFAULT '' COMMENT '短信id',
                `f_send_time` varchar(20) DEFAULT NULL,
                `f_type` enum('DX','WX','JS') DEFAULT 'DX' COMMENT 'DX.短信 WX.微信 JS.极速版',
                `f_mail_no` varchar(50) DEFAULT NULL COMMENT '运单号',
                `f_recipient_mobile` bigint(11) DEFAULT NULL COMMENT '收件人手机号',
                `f_sms_content` text COMMENT 'f_sms_content',
                `f_send_notice` tinyint(4) DEFAULT NULL COMMENT '发送状态',
                `f_success_notice` varchar(20) DEFAULT NULL COMMENT '回调状态',
                `f_success_time` varchar(20) DEFAULT NULL COMMENT '回调时间',
                `f_station_id` int(10) DEFAULT NULL COMMENT '站点id',
                `f_reduce_num` tinyint(2) DEFAULT NULL COMMENT '短信扣费条数',
                `f_send_sms_type` tinyint(2) DEFAULT NULL COMMENT '短信发送类型：0.队列发送  1.重新发送',
                `f_send_time_stamp` int(11) DEFAULT NULL,
                `f_success_time_stamp` int(11) DEFAULT NULL,
                PRIMARY KEY (`f_parcel_id`,`f_massage_id`),
                KEY `f_massage_id` (`f_massage_id`),
                KEY `f_station_id` (`f_station_id`),
                KEY `f_type` (`f_type`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
        ");

    }

    /**
     * 统计包裹失败次数 以便备用接口重发
     * @param unknown $parcelId
     */
    public function queryFailCount($parcelId){
        // 只查询已回调并且状态为失败的情况
        $where = "`f_parcel_id`='{$parcelId}' and f_success_notice <> 'DELIVRD' and f_success_time IS NOT NULL";
        
        return $this->getConditionTable_Result(
            date( 'Y-m-d' ),
            date( 'Y-m-d' ),
            'f_parcel_id',
            $where
        )->count('f_parcel_id');
    }
}